//download.js v4.2, by dandavis; 2008-2016. [MIT] see http://danml.com/download.html for tests/usage
// v1 landed a FF+Chrome compat way of downloading strings to local un-named files, upgraded to use a hidden frame and optional mime
// v2 added named files via a[download], msSaveBlob, IE (10+) support, and window.URL support for larger+faster saves than dataURLs
// v3 added dataURL and Blob Input, bind-toggle arity, and legacy dataURL fallback was improved with force-download mime and base64 support. 3.1 improved safari handling.
// v4 adds AMD/UMD, commonJS, and plain browser support
// v4.1 adds url download capability via solo URL argument (same domain/CORS only)
// v4.2 adds semantic variable names, long (over 2MB) dataURL support, and hidden by default temp anchors
// https://github.com/rndme/download
import Id3 from 'browser-id3-writer';
import timer from './timer';

export default function download(data, strFileName, strMimeType = null, songInfo = null, cb = {}) {
    var self = window, // this script is only for browsers anyway...
        defaultMime = "application/octet-stream", // this default mime also triggers iframe downloads
        mimeType = strMimeType || defaultMime,
        payload = data,
        url = data,
        anchor = document.createElement("a"),
        toString = function (a) {
            return String(a);
        },
        myBlob = (self.Blob || self.MozBlob || self.WebKitBlob || toString),
        fileName = strFileName || "download",
        blob,
        reader,
        myBlob = myBlob.call ? myBlob.bind(self) : Blob;

    if (String(this) === "true") { //reverse arguments, allowing download.bind(true, "text/xml", "export.xml") to act as a callback
        payload = [payload, mimeType];
        mimeType = payload[0];
        payload = payload[1];
    }


    if (url && url.length < 2048) { // if no filename and no mime, assume a url was passed as the only argument

        anchor.href = url; // assign href prop to temp anchor
        if (anchor.href.indexOf(url) !== -1) { // if the browser determines that it's a potentially valid url path:
            var ajax = new XMLHttpRequest();
            ajax.open("GET", url, true);
            ajax.responseType = 'arraybuffer';
            ajax.onload = function (e) {
                if (e.currentTarget.status === 200) {
                    var downInfo = e.target.response;
                    // 下面是下载歌曲图片，通过 id3 加到歌曲信息中，这样就能显示图片了
                    // 网易云的如果来源是qq,暂不添加id3
                    if (
                        !(songInfo.platform === '163' && songInfo.qqId) &&
                        songInfo && songInfo.al && songInfo.al.picUrl
                    ) {
                        try {
                            var coverAjax = new XMLHttpRequest();
                            coverAjax.open(
                                'GET',
                                songInfo.al.picUrl.replace(/http(s|):\/\/y\.gtimg\.cn/, `http://${window.location.host}/qqImg`).replace('300x300', '500x500'),
                                true
                            );
                            coverAjax.responseType = 'arraybuffer';
                            coverAjax.onload = function (cE) {
                                try {
                                    if (cE.currentTarget.status === 200) {
                                        const writer = new Id3(e.target.response);
                                        writer.setFrame('TIT2', songInfo.name)
                                            .setFrame('TPE1', songInfo.ar.map(a => a.name))
                                            .setFrame('TALB', songInfo.al.name)
                                            .setFrame('TRCK', songInfo.trackNo || '')
                                            .setFrame('APIC', {
                                                type: 3,
                                                data: coverAjax.response,
                                                description: songInfo.al.name,
                                            });
                                        songInfo.publishTime && writer.setFrame('TYER', timer(songInfo.publishTime).str('YYYY'));
                                        writer.addTag();
                                        downInfo = writer.arrayBuffer;
                                    }
                                } catch (err) {
                                    console.log('DOWN ERR: ', err);
                                }
                                setTimeout(() => {
                                    cb.success && cb.success();
                                    download(downInfo, fileName, defaultMime);
                                }, 10);
                            };

                            coverAjax.send();
                        } catch (err) {
                            cb.success && cb.success();
                            download(downInfo, fileName, defaultMime);
                        }
                    } else {
                        cb.success && cb.success();
                        download(downInfo, fileName, defaultMime);
                    }
                }
                cb.error && cb.error();
            };
            // 下载进度
            ajax.addEventListener('progress', function (e) {
                if (e.lengthComputable) {
                    var percentComplete = e.loaded / e.total;
                    cb.progress && cb.progress(percentComplete, e.loaded, e.total);
                }
            });
            setTimeout(function () {
                ajax.send();
            }, 0); // allows setting custom ajax headers using the return:
            // 创建之后的回调，这个ajax可以方便用来取消等。
            cb.init && cb.init(ajax);
            return ajax;
        } // end if valid url?
    } // end if url?


    //go ahead and download dataURLs right away
    if (/^data:([\w+-]+\/[\w+.-]+)?[,;]/.test(payload)) {

        if (payload.length > (1024 * 1024 * 1.999) && myBlob !== toString) {
            payload = dataUrlToBlob(payload);
            mimeType = payload.type || defaultMime;
        } else {
            return navigator.msSaveBlob ?  // IE10 can't do a[download], only Blobs:
                navigator.msSaveBlob(dataUrlToBlob(payload), fileName) :
                saver(payload); // everyone else can save dataURLs un-processed
        }

    } else {//not data url, is it a string with special needs?
        if (/([\x80-\xff])/.test(payload)) {
            var i = 0, tempUiArr = new Uint8Array(payload.length), mx = tempUiArr.length;
            for (i; i < mx; ++i) tempUiArr[i] = payload.charCodeAt(i);
            payload = new myBlob([tempUiArr], {type: mimeType});
        }
    }
    blob = payload instanceof myBlob ?
        payload :
        new myBlob([payload], {type: mimeType});


    function dataUrlToBlob(strUrl) {
        var parts = strUrl.split(/[:;,]/),
            type = parts[1],
            decoder = parts[2] == "base64" ? atob : decodeURIComponent,
            binData = decoder(parts.pop()),
            mx = binData.length,
            i = 0,
            uiArr = new Uint8Array(mx);

        for (i; i < mx; ++i) uiArr[i] = binData.charCodeAt(i);

        return new myBlob([uiArr], {type: type});
    }

    function saver(url, winMode) {

        if ('download' in anchor) { //html5 A[download]
            anchor.href = url;
            anchor.setAttribute("download", fileName);
            anchor.className = "download-js-link";
            anchor.innerHTML = "downloading...";
            anchor.style.display = "none";
            document.body.appendChild(anchor);
            setTimeout(function () {
                anchor.click();
                document.body.removeChild(anchor);
                if (winMode === true) {
                    setTimeout(function () {
                        self.URL.revokeObjectURL(anchor.href);
                    }, 250);
                }
            }, 66);
            return true;
        }

        // handle non-a[download] safari as best we can:
        if (/(Version)\/(\d+)\.(\d+)(?:\.(\d+))?.*Safari\//.test(navigator.userAgent)) {
            if (/^data:/.test(url)) url = "data:" + url.replace(/^data:([\w\/\-\+]+)/, defaultMime);
            if (!window.open(url)) { // popup blocked, offer direct download:
                if (confirm("Displaying New Document\n\nUse Save As... to download, then click back to return to this page.")) {
                    location.href = url;
                }
            }
            return true;
        }

        //do iframe dataURL download (old ch+FF):
        var f = document.createElement("iframe");
        document.body.appendChild(f);

        if (!winMode && /^data:/.test(url)) { // force a mime that will download:
            url = "data:" + url.replace(/^data:([\w\/\-\+]+)/, defaultMime);
        }
        f.src = url;
        setTimeout(function () {
            document.body.removeChild(f);
        }, 333);

    }//end saver

    if (navigator.msSaveBlob) { // IE10+ : (has Blob, but not a[download] or URL)
        return navigator.msSaveBlob(blob, fileName);
    }

    if (self.URL) { // simple fast and modern way using Blob and URL:
        saver(self.URL.createObjectURL(blob), true);
    } else {
        // handle non-Blob()+non-URL browsers:
        if (typeof blob === "string" || blob.constructor === toString) {
            try {
                return saver("data:" + mimeType + ";base64," + self.btoa(blob));
            } catch (y) {
                return saver("data:" + mimeType + "," + encodeURIComponent(blob));
            }
        }

        // Blob but not URL support:
        reader = new FileReader();
        reader.onload = function (e) {
            saver(this.result);
        };
        reader.readAsDataURL(blob);
    }
    return true;
}
